<script setup lang="ts">
import { watch, watchEffect, reactive, ref } from 'vue';

interface IState {
    arr: number[];
    count: number;
}

const state = reactive<IState>({
    arr: [1, 2, 3],
    count: 0
});

const num = ref<number>(100);

setInterval(() => {
    state.count++;
    state.arr.push(state.count);
    num.value--;
}, 3000);

// watch 第1个参数：监听源，可以是响应式数据，也可以是函数；第2个参数：回调函数，监听源变化时执行；第3个参数：配置项

watch(state, (newVal, oldVal) => {
    // 1.监听1个响应式数据,数据源必须是响应式数据(ref/reactive/computed)
});

watch([state, num], ([newState, newNum], [oldState, oldNum]) => {
    // 2.监听多个响应式数据,监听源要写成数组形式,回调函数的参数也是数组形式 (ref和computed在watch中不需要写.value)
});

watch(
    () => state.count,
    (newVal, oldVal) => {
        // 3.监听响应式数据中的某个属性,必须写成箭头函数形式,或者用toRefs解构，转换成ref数据,因为单个属性不是响应式数据
    }
);

watch(
    () => state.arr,
    (newVal, oldVal) => {
        // 4.监听数组或对象时必须开启深度监听
    },
    {
        deep: true, // 深度监听 (监听数组或对象时必须开启深度监听)
        immediate: true // 立即执行
    }
);

// watchEffect会自动监听内部所有响应式数据，不需要手动传入；watchEffect内部数据变化时，会自动执行；只能获得改变后的值，无法获得改变前的值
watchEffect(() => {
    // console.log('state.count: ', state.count); // state.count变化时，console.log会自动执行
});
</script>

<template>
    <div class="main_box">
        <h1>这个案例主要是 vue3 watch监听/ watchEffect监听</h1>

        <div class="main_row">
            <p>
                watch
                第1个参数：监听源，可以是响应式数据，也可以是函数；第2个参数：回调函数，监听源变化时执行；第3个参数：配置项
            </p>
            <p>
                watchEffect会自动监听内部所有响应式数据，不需要手动传入；watchEffect内部数据变化时，会自动执行；只能获得改变后的值，无法获得改变前的值
            </p>
            <p>1.watch监听1个响应式数据,数据源必须是响应式数据(ref/reactive/computed)</p>
            <p>
                2.watch监听多个响应式数据,监听源要写成数组形式,回调函数的参数也是数组形式
                (ref和computed在watch中不需要写.value)
            </p>
            <p>
                3.watch监听响应式数据中的某个属性,必须写成箭头函数形式,或者用toRefs解构，转换成ref数据,因为单个属性不是响应式数据
            </p>
            <p>4.watch监听数组或对象时必须开启深度监听</p>
        </div>

        <div class="main_text">
            <p>watch是惰性监听，需指定监听源，可以获得改变前后的值，数组和对象需要开启深度监听。</p>
            <p>watchEffect自动收集依赖，创建立即执行，无法获得改变前的值。</p>
        </div>
    </div>
</template>

<style scoped></style>
